"""工作空间数据模型"""

from pydantic import BaseModel, Field
from pathlib import Path
from datetime import datetime
from typing import Optional, List, Dict, Any
import uuid


class Workspace(BaseModel):
    """工作空间模型"""
    id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="工作空间唯一标识")
    name: str = Field(..., description="工作空间名称")
    root_path: Path = Field(..., description="根目录路径")
    created_at: datetime = Field(default_factory=datetime.now, description="创建时间")
    last_accessed: Optional[datetime] = Field(None, description="最后访问时间")
    is_active: bool = Field(default=True, description="是否激活")
    total_directories: int = Field(default=0, description="目录总数")
    total_files: int = Field(default=0, description="文件总数")
    metadata: Dict[str, Any] = Field(default_factory=dict, description="额外元数据")

    class Config:
        """Pydantic配置"""
        # 支持Path类型的序列化
        json_encoders = {
            Path: str,
            datetime: lambda v: v.isoformat()
        }

    def update_stats(self, directories: int, files: int) -> None:
        """更新统计信息"""
        self.total_directories = directories
        self.total_files = files
        self.last_accessed = datetime.now()

    def is_valid_path(self) -> bool:
        """检查路径是否有效"""
        return self.root_path.exists() and self.root_path.is_dir()

    def get_display_name(self) -> str:
        """获取显示名称"""
        return f"{self.name} ({self.root_path})"


class WorkspaceConfig(BaseModel):
    """工作空间配置"""
    workspace_id: str = Field(..., description="工作空间ID")
    auto_scan: bool = Field(default=True, description="自动扫描目录变化")
    scan_interval: int = Field(default=300, description="扫描间隔(秒)")
    max_depth: int = Field(default=10, description="最大扫描深度")
    exclude_patterns: List[str] = Field(
        default_factory=lambda: [".*", "__pycache__", "node_modules"],
        description="排除模式"
    )
    include_hidden: bool = Field(default=False, description="包含隐藏文件")
    
    class Config:
        json_encoders = {
            datetime: lambda v: v.isoformat()
        }